import StringBuilder from "../core/string-builder";
import moment from "moment";
import P from "../core/p";

/**
 * 国际化使用中国的
 */
moment.locale('zh-cn');

/**
 * 将日期格式化成字符串
 *
 * @param val - Date 对象或时间戳
 * @param pattern - 日期格式
 * @returns 格式化后的日期时间字符串
 */
const format = (val, pattern) => {
    return moment(new Date(val)).format(pattern);
};

/**
 * 格式化为完整日期时间字符串
 *
 * @param val - Date 对象或时间戳
 * @returns 格式化后的日期时间字符串
 */
const datetime = (val) => {
    return moment(new Date(val)).format(P.datetime);
};

/**
 * 格式化为紧凑日期时间字符串
 *
 * @param val - Date 对象或时间戳
 * @returns 格式化后的日期时间字符串
 */
const compactDatetime = (val) => {
    return moment(new Date(val)).format(P.compact_datetime);
};

/**
 * 格式化为日期字符串
 *
 * @param val - Date 对象或时间戳
 * @returns 格式化后的日期字符串
 */
const date = (val) => {
    return moment(new Date(val)).format(P.date);
};

/**
 * 格式化为紧凑日期字符串
 *
 * @param val - Date 对象或时间戳
 * @returns 格式化后的日期字符串
 */
const compactDate = (val) => {
    return moment(new Date(val)).format(P.compact_date);
};

/**
 * 转换为日期类型
 *
 * @param val - 任意类型的值
 * @returns 转换后的日期对象
 */
const toDate = (val) => {
    if (Date.prototype.isPrototypeOf(val)) {
        return val;
    } else if (typeof val === 'string') {
        return new Date(val);
    } else if (typeof val === 'number') {
        return new Date(val);
    } else {
        return caseObjectToDate(val);
    }
};

/**
 * 处理日期对象，这是后台 Date() 对象格式化之后的格式
 *
 * @param obj - 日期对象
 * @returns {Date}
 */
const caseObjectToDate = (obj) => {
    // 创建一个新的Date对象
    let date = new Date();

    // 设置年份、月份
    date.setFullYear(obj.year);
    // 月份从0开始计数，所以要减1
    date.setMonth(obj.monthValue - 1);
    date.setDate(obj.dayOfMonth);

    // 设置小时、分钟、秒和毫秒
    date.setHours(obj.hour);
    date.setMinutes(obj.minute);
    date.setSeconds(obj.second);
    return date;
};

/**
 * 将日期对象转换为日期字符串
 *
 * @param obj - 日期对象
 * @returns 格式化后的日期字符串
 */
const objectToDate = (obj) => {
    return new StringBuilder()
        .append(obj.year).append('-')
        .appendNumber(obj.monthValue, 2).append('-')
        .appendNumber(obj.dayOfMonth, 2)
        .build();
};

/**
 * 将日期对象转换为日期时间字符串
 *
 * @param obj - 日期对象
 * @returns YYYY-MM-DD HH:mm:ss 格式的日期时间字符串
 */
const objectToDatetime = (obj) => {
    return new StringBuilder()
        .append(obj.year).append('-')
        .appendNumber(obj.monthValue, 2).append('-')
        .appendNumber(obj.dayOfMonth, 2).append(' ')
        .appendNumber(obj.hour, 2).append(':')
        .appendNumber(obj.minute, 2).append(':')
        .appendNumber(obj.second, 2)
        .build();
};

/**
 * 将日期对象转换为紧凑日期字符串
 *
 * @param obj - 日期对象
 * @returns YYYYMMDD 格式的日期字符串
 */
const objectToCompactDate = (obj) => {
    return new StringBuilder()
        .append(obj.year)
        .appendNumber(obj.monthValue, 2)
        .appendNumber(obj.dayOfMonth, 2)
        .build();
};

/**
 * 将日期对象转换为紧凑日期时间字符串
 * @param obj - 日期对象
 * @returns YYYYMMDDHHmmss 格式的日期时间字符串
 */
const objectToCompactDatetime = (obj) => {
    return new StringBuilder()
        .append(obj.year)
        .appendNumber(obj.monthValue, 2)
        .appendNumber(obj.dayOfMonth, 2)
        .appendNumber(obj.hour, 2)
        .appendNumber(obj.minute, 2)
        .appendNumber(obj.second, 2)
        .build();
};

/**
 * 日期对象转换函数
 * @param obj - 日期对象
 * @param pattern - 格式模式
 * @returns 格式化后的日期字符串
 */
const formatDateObject = (obj, pattern) => {
    const builder = new StringBuilder();
    if (pattern.includes('YYYY')) builder.append(obj.year);
    if (pattern.includes('MM')) builder.appendNumber(obj.monthValue, 2);
    if (pattern.includes('DD')) builder.appendNumber(obj.dayOfMonth, 2);
    if (pattern.includes('HH')) builder.appendNumber(obj.hour, 2);
    if (pattern.includes('mm')) builder.appendNumber(obj.minute, 2);
    if (pattern.includes('ss')) builder.appendNumber(obj.second, 2);
    return builder.build();
};

/**
 * 简洁的流逝时间格式（省略不足一天的数据）
 *
 * @param millis - 时间毫秒数
 * @returns 流逝时间字符串（如 "3天"）
 */
const elapsedTime = (millis) => {
    const ms = Math.abs(millis);
    if (ms > 86400000) {
        return Math.round(ms / 86400000) + '天';
    } else if (ms > 3600000) {
        return Math.round(ms / 3600000) + '小时';
    } else if (ms > 60000) {
        return Math.round(ms / 60000) + '分';
    } else {
        return Math.round(ms / 1000) + '秒';
    }
};

/**
 * 完整的流逝时间格式（省略 0 值）
 *
 * @param millis - 时间毫秒数
 * @returns 流逝时间字符串（如 "3天12分"）
 */
const fullyElapsedTime = (millis) => {
    const builder = new StringBuilder();
    let ms = Math.abs(millis);
    let d = Math.floor(ms / 86400000);
    ms %= 86400000;
    let h = Math.floor(ms / 3600000);
    ms %= 3600000;
    let m = Math.floor(ms / 60000);
    ms %= 60000;
    let s = Math.floor(ms / 1000);
    if (d !== 0) builder.append(d).append('天');
    if (h !== 0) builder.append(h).append('小时');
    if (m !== 0) builder.append(m).append('分');
    if (s !== 0) builder.append(s).append('秒');
    return builder.build();
};

/**
 * 完整的流逝时间格式（保留 0 值）
 *
 * @param millis - 时间毫秒数
 * @returns 流逝时间字符串（如 "3天0小时12分0秒"）
 */
const fullyElapsedTime2 = (millis) => {
    let ms = Math.abs(millis);
    const build = new StringBuilder();
    build.append(Math.floor(ms / 86400000)).append('天');
    ms %= 86400000;
    build.append(Math.floor(ms / 3600000)).append('小时');
    ms %= 3600000;
    build.append(Math.floor(ms / 60000)).append('分');
    ms %= 60000;
    build.append(Math.floor(ms / 1000)).append('秒');
    return build.build();
};

export default {
    // date format
    format, date, datetime, compactDate, compactDatetime,

    // others case to date
    toDate, caseObjectToDate,

    // json-date case to string
    objectToDate, objectToDatetime, objectToCompactDate, objectToCompactDatetime, formatDateObject,

    // others
    elapsedTime, fullyElapsedTime, fullyElapsedTime2
};